<?php

namespace App\Http\Controllers\Backend\Flaw;

use App\Models\Flaw\VulsRecord;
use App\Models\Ogz;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Flaw\Vuls;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Cache;
use App\Http\Controllers\Traits\Base;
use App\Models\App;

class AdditionController extends Controller
{
    use Base;
    //缓存实时更新开关
    protected  $cache;
    //漏洞列表搜索功能
    public function search(Request $request){
        //获取该用户所拥有的app权限
        $source =auth()->user()->source;
        $apps = $this->userLinks();
        $this->cache = true;
        $where = array();
        $orWhere =array('title'=>array(),'description'=>array());
        $whereBetween = array('start'=>'','end'=>'');
        isset($request->startTime)? $whereBetween['start'] = date('Y-m-d',strtotime($request->startTime)): 1;
        isset($request->endTime)? $whereBetween['end'] = date('Y-m-d',strtotime($request->endTime)): 1;
        isset($request->uName)? $where[] = ['vuls.user_id','=',$request->uName]: 1;
        isset($request->searchCategory)? $where[] = ['vuls.category_id','=',$request->searchCategory]: 1;
        isset($request->searchLevel)? $where[] = ['vuls.level_id','=',$request->searchLevel]: 1;
        isset($request->searchStatus) && $request->searchStatus!= 100 ? $where[] = ['vuls.status','=',$request->searchStatus]: 1;
        /*此功能暂不开放*/
        /*        isset($request->searchDel)? $where[] = ['vuls.is_delete','=',$request->searchDel]: 1;*/
        /*此功能暂不开放*/
        isset($request->searchKeywords)? $orWhere['title'][] = ['vuls.title','like','%'.$request->searchKeywords.'%']: 1;
        isset($request->searchKeywords)? $orWhere['description'][] = ['vuls.description','like','%'.$request->searchKeywords.'%']: 1;
        $whereBetween = !($whereBetween['start'] && $whereBetween['end']) ?array() : $whereBetween;
       //where 条件空查询所有
        !$where ? $where[] = ['vuls.id','>',0] : $where;
        //当前用户拥有的应用;
        if(!empty($request->searchApp)){
            $searchApps=[$request->searchApp];
        }else{
            if(!empty($request->searchOgz)){
                $ogzIds = VulsRecord::getOgzRelateInfo($request->searchOgz, false, true, true);
                $appids =  DB::table('app')->whereIn('ogz_id',$ogzIds)->whereIn('id',$apps['apps'])->pluck('id')->toArray();
                $searchApps= $appids;
            }

        }
        $accessSel = empty($searchApps) && empty($request->searchOgz) ? $apps['apps'] : $searchApps;
        //待评分
        if(intval($request->searchStatus) == 100){
            $where[] = ['vuls.reward','>',0];
            $where[] = ['vuls.is_reasonable','<>',2];
            $where[] = ['vuls.status','>=',Vuls::BEREPAIRE];
        }
        $searchLists = Vuls::unionSelect($accessSel,$where,$orWhere,$whereBetween);
        if($this->cache){
            $restructureData = $this->restructureData($searchLists['export']);
            $ogzName = empty($request->searchOgz) ? '所有' : Ogz::where('id', '=', $request->searchOgz )->value('name');
            Cache::put('searchList-'.Auth::id(), $restructureData,10);
            Cache::put('ogzName-'.Auth::id(), $ogzName,10);
            $this->cache =true;
        }
        $colls = Vuls::searchVarCol($apps);
        $vlists = Vuls::unionSelect($accessSel,$where,$orWhere,$whereBetween);
        $lists =!$request->isMethod('post')&&!$request->is('admin/vulsSearch/searchStatus/*')? $vlists['paginate']: $searchLists['paginate'];
        $type = $request->type? 1 : 0;
        //为分页增加搜索条件
        $lists = $lists->appends(Input::except('page'));
        /*应用*/
        if(!empty($request->searchOgz)){
            $ogzIds = VulsRecord::getOgzRelateInfo($request->searchOgz, false, true, true);
            $appIds =  DB::table('app')->whereIn('ogz_id',$ogzIds)->whereIn('id',$apps['apps'])->get();
        }else{
            $appIds = DB::table('app')->select('*')->whereIn('id',$apps['apps'])->get(); ;
        }
        //统计数据
        $static = Vuls::statusNumber($apps['apps']);
        $static[5] = Vuls::BecommitNumer($apps['apps']);
        $lists = Vuls::extendAttr($lists);
        return view('backend.flaw.vulslist', [
                'lists' => $lists,
                'vulStatus' => Vuls::$vulsStatus,
                'ulists' => $colls->ulists,
                'categorys' => $colls->categorys,
                'levels' => $colls->levels,
                'ogzs' => $colls->ogzs,
                'request' => $request,
                'type' => $type,
                'source' => $source,
                'app' => $request->searchApp,
                'apps' => $appIds,
                'static' => $static
            ]
        );
    }

    /**
     * searchAjax 所属机构联动数据请求返回
     * 
     * @param Request $request
     * @return mixed
     */
    public function searchAjax(Request $request){
        $apps = $this->userLinks();
        if($request->type == 'child'){
            return DB::table('app')->where('ogz_id','=',$request->id)->whereIn('id',$apps['apps'])->get();
        }else{
            return DB::table('ogz')->where('pid','=',$request->id)->whereIn('id',$apps['ogzs']['child'])->get();
        }
    }

    /**
     * appAjaxReturn 根据选择的机构返回下属所对应的所有应用
     * 
     * @param Request $request
     * @return mixed
     */
    public function appAjaxReturn(Request $request){
        $apps = $this->userLinks();
        if($request->id == -1){
            return  DB::table('app')->whereIn('id',$apps['apps'])->get();
        }else{
            $ogzIds = VulsRecord::getOgzRelateInfo($request->id, false, true, true);
            return DB::table('app')->whereIn('ogz_id',$ogzIds)->whereIn('id',$apps['apps'])->get();
        }
    }

    /**
     * exportVuls 导出筛选出来的数据，如果搜索条件发生变化则更新缓存，
     * 否则 使用原有数据
     *
     */
    public  function  exportVuls(){
        $toOneDim = (array_column(Vuls::$vulsStatus,0));
        $cellData = [
            ['ID','标题','提交人','应用名称','所属分类','漏洞级别','当前状态','修复用时(天)','所属板块',
                '所属公司','所属子公司', '创建日期','审核日期','邮件通知日期','确认日期','修复日期','解决日期','价值','延期时间','应用类型'
            ]
        ];
        $fillField = array();
        //如果缓存更新了，使用最新的，否则使用旧的
        $data = $this->cache ? Cache::pull('searchList-'.Auth::id()) : Cache::get('searchList-'.Auth::id());
        $ogzName = $this->cache ? Cache::pull('ogzName-'.Auth::id()) : Cache::get('ogzName-'.Auth::id());
        $this->cache = false;
        if (!$data)abort(500,'要导出数据为空，请根据筛选条件导出！');
        foreach ($data as $d){
            $fillField[] = $d->vuls_number;
            $fillField[] = $d->title;
            $fillField[] = $d->uname;
            $fillField[] = $d->aname;
            $fillField[] = $d->cname;
            $fillField[] = $d->lname;
            $fillField[] = $toOneDim[$d->status];
            $fillField[] = $d->repairUseTime;
            $fillField[] = $d->plate;
            $fillField[] = $d->company;
            $fillField[] = $d->subCompany;
            $fillField[] = $d->created_at;
            $fillField[] = $d->auditDate;
            $fillField[] = $d->check_at;
            $fillField[] = $d->confirmDate;
            $fillField[] = $d->repairDate;
            $fillField[] = $d->solveDate;
            $fillField[] = Vuls::getValue($d->level_id);
            if ($d->delayed_at){
                $fillField[] = Vuls::getDelayedDay($d->id);
            }else{
                $fillField[] = 0;
            }
            $fillField[] = App::$type[intval($d->type)];
            $cellData[] = $fillField;
            $fillField = array();
        }
        $excelTitle = $ogzName.'-漏洞-'.date('Ymds',time());
        Excel::create($excelTitle,function($excel) use ($cellData){
            $excel->sheet('vuls', function($sheet) use ($cellData){
                $sheet->rows($cellData);
                //mac乱码
                ob_end_clean();
            });
        })->export('xls');
    }

    /**
     * restructureData 对导出数据进行重组,增加组织机构列、修复用时列
     * 审核时间列、确认时间列、修复时间列、解决时间列
     *
     * @param array $data
     * @return array
     */
    private function restructureData($data = array()){
        foreach ($data as $v){
            $ogzNames = array_reverse(VulsRecord::getOgzRelateInfo($v->ogz_id, false));
            $v->repairUseTime = VulsRecord::getRepairUseTime($v->id, $v->check_at);
            $v->orgName = implode('->',array_slice($ogzNames, 0, 1));
            $v->plate = implode('->', array_slice($ogzNames, 1, 1));
            $v->company = implode('->', array_slice($ogzNames, 2, 1));
            $v->subCompany = implode('->', array_slice($ogzNames, 3));
            $v->auditDate = VulsRecord::getCreateTime($v->id, 2);
            $v->confirmDate = VulsRecord::getCreateTime($v->id, 3);
            $v->repairDate =VulsRecord::getCreateTime($v->id, 4);
            $v->solveDate = VulsRecord::getCreateTime($v->id, 5);
        }
        return $data;
    }
}
